<template>
  <div class="container">
    <a-card class="general-card" :title="$route.meta.locale">
      <table-search
        v-permission="'system:dept:query'"
        :fileds="searchFileds"
        @search="search"
        @reset="search"
      ></table-search>
      <xTable
        v-model:refresh="refresh"
        v-model:selected-keys="selectedKeys"
        :params="params"
        :columns="tableColumns"
        http-data-key="data"
        :http="{
          list: getListData,
          del: delDept,
          batchDel: delDept,
        }"
        :http-permission="{
          del: 'system:dept:remove',
        }"
        row-key="deptId"
        :format-data="formatTableData"
      >
        <template #operation-default>
          <div v-permission="'system:dept:add'" class="item">
            <a-button type="outline" @click="editOpen(null)"> 新增 </a-button>
          </div>
          <div v-permission="'system:dept:edit'" class="item">
            <a-button
              type="outline"
              status="success"
              @click="editOpen(selectedKeys)"
            >
              编辑
            </a-button>
          </div>
        </template>
        <template #status="{ row }">
          <dict-tag :options="dict.sys_normal_disable" :value="row.status" />
        </template>
        <template #optional="{ row }">
          <a-button
            v-permission="'system:dept:edit'"
            type="text"
            status="success"
            @click="editOpen(row.deptId)"
          >
            编辑
          </a-button>
        </template>
      </xTable>
    </a-card>
    <EditModal
      ref="edit"
      :default-value="{ orderNum: 0, status: defaultStatus }"
      :fields="editFields"
      :http-add="addDept"
      :http-edit="updateDept"
      :http-get="getDept"
      :get-handler="getHandler"
      @reload="refresh = true"
    >
    </EditModal>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, ref, computed, toRaw } from 'vue';
  import { addDateRange, listToTree } from '@/utils/index';
  import {
    getListData,
    getDept,
    addDept,
    updateDept,
    delDept,
  } from '@/api/system/dept';
  import { Message } from '@arco-design/web-vue';
  import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
  import { getDict } from '@/utils/dict';

  const dict = getDict('sys_normal_disable');
  const edit = ref();
  const selectedKeys = ref([]);
  const deptTree: any = ref([]);
  const initDeptTree = async () => {
    const { code, msg, data } = await getListData();
    if (code !== 200) {
      Message.error(msg);
    }
    deptTree.value = listToTree(
      data.map((item: { deptName: any; parentId: number; deptId: number }) => ({
        ...item,
        parentId: item.parentId === 0 ? null : item.parentId,
        id: item.deptId,
        key: item.deptId,
        title: item.deptName,
      })),
      'deptId',
      'parentId'
    );
  };

  // 定义查询字段
  const searchFileds: Array<any> = reactive([
    {
      span: 5,
      field: 'deptName',
      placeholder: '请输入部门名称',
      label: '部门名称',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 5,
      field: 'status',
      placeholder: '请选择状态',
      label: '状态',
      initValue: '',
      tag: 'a-select',
      attrs: {
        options: dict.sys_normal_disable,
      },
    },
  ]);
  // 定义表格字段
  const tableColumns: Array<TableColumnData> = reactive([
    {
      dataIndex: 'deptName',
      title: '部门名称',
    },
    {
      dataIndex: 'orderNum',
      title: '排序',
    },
    {
      dataIndex: 'status',
      title: '状态',
      slotName: 'status',
    },
    {
      dataIndex: 'createTime',
      title: '创建时间',
    },
    {
      dataIndex: 'optional',
      title: '操作',
      slotName: 'optional',
    },
  ]);
  const editFields: Array<any> = reactive([
    {
      key: 'parentId',
      label: '上级部门',
      placeholder: '请选择上级部门',
      tag: 'a-tree-select',
      span: 24,
      attrs: {
        'data': deptTree,
        'treeProps': {
          virtualListProps: {
            height: 200,
          },
        },
        'allow-search': true,
        'allow-clear': true,
        'filter-tree-node': (
          searchValue: string,
          nodeData: { title: string }
        ) => {
          return (
            String(nodeData.title)
              .toLowerCase()
              .indexOf(String(searchValue).toLowerCase()) > -1
          );
        },
      },
      decorator: {
        rules: [{ required: true, message: '请选择上级部门' }],
      },
    },
    {
      key: 'deptName',
      label: '部门名称',
      placeholder: '请输入部门名称',
      tag: 'a-input',
      span: 12,
      attrs: {},
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [{ required: true, message: '请输入部门名称' }],
      },
    },
    {
      key: 'orderNum',
      label: '显示排序',
      placeholder: '请输入显示排序',
      tag: 'a-input-number',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [{ required: true, message: '请输入显示排序' }],
      },
    },
    {
      key: 'leader',
      label: '负责人',
      placeholder: '请输入负责人',
      span: 12,
      tag: 'a-input',
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [{ required: false, message: '请输入负责人' }],
      },
    },
    {
      key: 'phone',
      label: '联系电话',
      placeholder: '请输入联系电话',
      span: 12,
      tag: 'a-input',
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [
          {
            validator: (value: string, cb: (arg0: string) => void) => {
              const reg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
              if (!reg.test(value)) {
                cb('请输入正确的手机号码');
              }
            },
          },
        ],
      },
    },
    {
      key: 'email',
      label: '邮箱',
      placeholder: '请输入邮箱',
      span: 12,
      tag: 'a-input',
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [{ type: 'email', message: '请输入正确的邮箱地址' }],
      },
    },
    {
      key: 'status',
      label: '状态',
      placeholder: '请选择状态',
      tag: 'a-radio-group',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {
        options: dict.sys_normal_disable,
      },
      decorator: {
        rules: [{ required: false, message: '请选择状态' }],
      },
    },
  ]);
  const refresh = ref(true);
  // 定义表格查询参数
  const params = ref({
    dateRange: [],
  });
  const defaultStatus = computed(() => {
    if (dict.sys_normal_disable.value <= 0) {
      return '0';
    }
    const list = toRaw(dict.sys_normal_disable);
    return list.value.find((item: { default: any }) => item.default).value;
  });
  // 定义搜索方法
  const search = (data: any) => {
    params.value = addDateRange(data, data?.dateRange);
    refresh.value = true;
  };
  const formatTableData = (data: any) => {
    const datas = listToTree(
      data.map((item: { parentId: number; deptId: number }) => ({
        ...item,
        parentId: item.parentId === 0 ? null : item.parentId,
        id: item.deptId,
      })),
      'deptId',
      'parentId'
    );
    return datas;
  };

  const editOpen = async (keys: any | any[]) => {
    await initDeptTree();
    if (Array.isArray(keys) && keys.length === 1) {
      edit.value.show(keys[0]);
    } else if (!Array.isArray(keys)) {
      edit.value.show(keys);
    } else if (Array.isArray(keys) && keys.length < 1) {
      Message.warning('必须选中一条数据');
    } else if (Array.isArray(keys) && keys.length > 1) {
      Message.warning('只能选中一条数据');
    }
  };

  const getHandler = ({ data }: { [x: string]: any }) => {
    return {
      ...data,
      orderNum: Number(data.orderNum),
    };
  };
</script>

<style scoped lang="less">
  .operation-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-bottom: 20px;
    .item {
      margin-left: 8px;
    }
  }
  .container {
    // padding: 0 20px 20px 20px;
  }
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
